home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_052 / tek4010 / xmodem.c < prev   
C/C++ Source or Header  |  1992-05-06  |  9KB  |  297 lines

  1. /*************************************************************
  2.  * vt100 terminal emulator - XMODEM protocol support
  3.  *
  4.  *           860823 DBW - Integrated and rewrote lots of code
  5.  *           860815 Steve Drew: readchar inproved with real timeouts
  6.  *      v2.0 860809 DBW - Major rewrite
  7.  *      v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
  8.  *      v1.0 860712 DBW - First version released
  9.  *
  10.  *************************************************************/
  11.  
  12. #define MODULE_XMODEM 1
  13. #include "vt100.h"
  14.  
  15. /* forward declarations for LATTICE */
  16. void sendstring();
  17. void sendchar();
  18.  
  19. /************************************************************
  20. * Send a string (using sendchar below)
  21. ************************************************************/
  22.  
  23. void sendstring(s)
  24. char *s;
  25.     {
  26.     char c;
  27.  
  28.     while ((c = *s++) != '\000') sendchar(c);
  29.     }
  30.  
  31. /**************************************************************/
  32. /* send char and read char functions for the xmodem function */
  33. /************************************************************/
  34. void sendchar(ch)
  35. int ch;
  36.     {
  37.     rs_out[0] = ch & 0xFF;
  38.     DoIO(Write_Request);
  39.     }
  40.  
  41. int readchar()
  42.     {
  43.     int rd,ch;
  44.     
  45.     Timer.tr_time.tv_secs = ttime;
  46.     Timer.tr_time.tv_micro = 0;
  47.     SendIO((char *) &Timer.tr_node);
  48.     
  49.     rd = FALSE;
  50.     while (rd == FALSE)  
  51.         {       
  52.         Wait((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) |
  53.             ( 1L << mywindow->UserPort->mp_SigBit) |
  54.             ( 1L << Timer_Port->mp_SigBit));
  55.         if (CheckIO(Read_Request))
  56.             {
  57.             WaitIO(Read_Request);
  58.             ch=rs_in[0];
  59.             rd = TRUE;
  60.             BeginIO(Read_Request);
  61.             }
  62.         if (NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
  63.            if ((NewMessage->Class == RAWKEY) && (NewMessage->Code == 69))
  64.                  {
  65.                  AbortIO((char *) &Timer);
  66.                  Wait (1L << Timer_Port->mp_SigBit);
  67.                  if (want_message) 
  68.                    emits("\nUser aborted transfer\n");
  69.                  timeout = USERABORT;
  70.                  return('\0');
  71.                  }
  72.             continue;
  73.             }
  74.         if (rd == FALSE && CheckIO(&Timer)) {
  75.             if (want_message)
  76.               emits("\nTimeout waiting for character\n");
  77.             timeout = TIMEOUT;
  78.             return('\0');
  79.             }
  80.         }     /* end while */
  81.     AbortIO((char *) &Timer);
  82.     Wait (1L << Timer_Port->mp_SigBit);
  83.     timeout = GOODREAD;
  84.     return(ch & 0xFF);
  85.     }
  86.  
  87. /**************************************/
  88. /* xmodem send and recieve functions */
  89. /************************************/
  90.  
  91. int XMODEM_Read_File(file)
  92. char *file;
  93.     {
  94.     int firstchar, sectnum, sectcurr, sectcomp, errors, errorflag;
  95.     unsigned int checksum, j, bufptr;
  96.     char numb[10];
  97.     bytes_xferred = 0L;
  98.     ttime = TTIME_SHORT;
  99.     want_message = TRUE; /* tell readchar to print any error msgs */
  100.  
  101.     if ((fd = creat(file, 0)) < 0)
  102.         {
  103.         emits("Cannot Open File\n");
  104.         return FALSE;
  105.         }
  106.     else
  107.     emits("Receiving File\n\nType <ESC> to abort transfer\n");
  108.  
  109.     sectnum = errors = bufptr = 0;
  110.     sendchar(NAK);
  111.     firstchar = 0;
  112.     while (firstchar != EOT && errors != ERRORMAX)
  113.         {
  114.         errorflag = FALSE;
  115.  
  116.         do {                                    /* get sync char */
  117.             firstchar = readchar();
  118.             if (timeout != GOODREAD) {
  119.                 if (timeout == USERABORT || errors++ == ERRORMAX)
  120.                     return FALSE;
  121.                 }
  122.             } while (firstchar != SOH && firstchar != EOT);
  123.  
  124.         if  (firstchar == SOH)
  125.             {
  126.             emits("Getting Block ");
  127.             sprintf(numb, "%d", sectnum);
  128.             emits(numb);
  129.             emits("...");
  130.             sectcurr = readchar();
  131.             if (timeout != GOODREAD) return FALSE;
  132.             sectcomp = readchar();
  133.             if (timeout != GOODREAD) return FALSE;
  134.             if ((sectcurr + sectcomp) == 255)
  135.                 {
  136.                 if (sectcurr == ((sectnum + 1) & 0xff))
  137.                     {
  138.                     checksum = 0;
  139.                     for (j = bufptr; j < (bufptr + SECSIZ); j++)
  140.                         {
  141.                         bufr[j] = readchar();
  142.                         if (timeout != GOODREAD) return FALSE;
  143.                         checksum = (checksum + bufr[j]) & 0xff;
  144.                         }
  145.                     if (checksum == readchar() && timeout == GOODREAD)
  146.                         {
  147.                         errors = 0;
  148.                         sectnum++;
  149.                         bufptr += SECSIZ;
  150.                         bytes_xferred += SECSIZ;
  151.                         emits("verified\n");
  152.                         if (bufptr == BufSize)
  153.                             {
  154.                             if (write(fd, bufr, BufSize-128) == EOF)
  155.                                 {
  156.                                 emits("\nError Writing File\n");
  157.                                 return FALSE;
  158.                                 }
  159.                             bufptr = 128;
  160.                             for (j = 0; j < 128; j++)
  161.                                 bufr[j] = bufr[(BufSize-128)+j];
  162.                             }
  163.                         sendchar(ACK);
  164.                         }
  165.                     else
  166.                         {
  167.                         errorflag = TRUE;
  168.                         if (timeout == USERABORT) return FALSE;
  169.                         }
  170.                     }
  171.                 else
  172.                     {
  173.                     /* got a duplicate sector */        
  174.                     if (sectcurr == (sectnum & 0xff))
  175.                         {
  176.                         /* wait until we time out for 5secs */
  177.                         do {
  178.                             readchar();
  179.                             } while (timeout == GOODREAD);
  180.                         if (timeout == USERABORT) return FALSE;
  181.                         emits("\nReceived Duplicate Sector\n");
  182.                         sendchar(ACK);
  183.                         }
  184.                     else errorflag = TRUE;
  185.                     }
  186.                 }
  187.             else errorflag = TRUE;
  188.             }
  189.         if (errorflag == TRUE)
  190.             {
  191.             errors++;
  192.             emits("\nError\n");
  193.             sendchar(NAK);
  194.             }
  195.         }        /* end while */
  196.     if ((firstchar == EOT) && (errors < ERRORMAX))
  197.         {
  198.         sendchar(ACK);
  199.         while (bufptr > 0 && (bufr[--bufptr] == 0x00 ||
  200.                               bufr[bufptr]   == 0x1A)) ;
  201.         write(fd, bufr, ++bufptr);
  202.         close(fd);
  203.         return TRUE;
  204.         }
  205.     return FALSE;
  206.     }
  207.  
  208. int XMODEM_Send_File(file)
  209. char *file;
  210.     {
  211.     int sectnum, bytes_to_send, size, attempts, c;
  212.     unsigned checksum, j, bufptr;
  213.     char numb[10];
  214.     bytes_xferred = 0;
  215.     ttime = TTIME_LONG;
  216.     want_message = TRUE; /* tell readchar to print any error msgs */
  217.  
  218.     if ((fd = open(file, 0)) < 0) {
  219.         emits("Cannot Open Send File\n");
  220.         return FALSE;
  221.         }
  222.     else
  223.     emits("Sending File\n\nType <ESC> to abort transfer\n");
  224.     attempts = 0;
  225.     sectnum = 1;
  226.     /* wait for sync char */
  227.     j=1;
  228.     while (((c = readchar()) != NAK) && (j++ < ERRORMAX))
  229.         if (timeout == USERABORT) return(FALSE);
  230.     if (j >= (ERRORMAX))
  231.         {
  232.         emits("\nReceiver not sending NAKs\n");
  233.         return FALSE;
  234.         }
  235.  
  236.     while ((bytes_to_send = read(fd, bufr, BufSize)) && attempts != RETRYMAX)
  237.         {
  238.         if (bytes_to_send == EOF)
  239.             {
  240.             emits("\nError Reading File\n");
  241.             return FALSE;
  242.             }
  243.  
  244.         bufptr = 0;
  245.         while (bytes_to_send > 0 && attempts != RETRYMAX)
  246.             {
  247.             attempts = 0;
  248.             emits("Block ");
  249.             sprintf(numb, "%d ", sectnum);
  250.             emits(numb);
  251.             do {
  252.                 emits(".");    
  253.                 sendchar(SOH);
  254.                 sendchar(sectnum);
  255.                 sendchar(~sectnum);
  256.                 checksum = 0;
  257.                 size = SECSIZ <= bytes_to_send ? SECSIZ : bytes_to_send;
  258.                 bytes_to_send -= size;
  259.                 for (j = bufptr; j < (bufptr + SECSIZ); j++)
  260.                 if (j < (bufptr + size)) {
  261.                     sendchar(bufr[j]);
  262.                     checksum += bufr[j];
  263.                     }
  264.                 else sendchar(0);
  265.                 sendchar(checksum);
  266.                 attempts++;
  267.                 c = readchar();
  268.                 if (timeout == USERABORT) {emits("\n"); return FALSE;}
  269.                 } while ((c != ACK) && (attempts != RETRYMAX));
  270.             bufptr += size;
  271.             bytes_xferred += size;
  272.             emits(" sent\n");
  273.             sectnum++;
  274.             }
  275.         }
  276.     close(fd);
  277.     if (attempts == RETRYMAX)
  278.         {
  279.         emits("\nNo Acknowledgment Of Sector, Aborting\n");
  280.         return FALSE;
  281.         }
  282.     else
  283.         {
  284.         attempts = 0;
  285.         do {
  286.             sendchar(EOT);
  287.             attempts++;
  288.             } while ((readchar() != ACK) &&
  289.                      (attempts != RETRYMAX) &&
  290.                      (timeout != USERABORT)) ;
  291.         if (attempts == RETRYMAX)
  292.             emits("\nNo Acknowledgment Of End Of File\n");
  293.         }
  294.     return TRUE;
  295.     }
  296.  
  297.